﻿using System;
using System.Collections;
using System.Collections.Specialized;
using System.Configuration.Provider;
using System.Globalization;
using CustomsNuke.Engine.Properties;

namespace CustomsNuke.Engine.Security
{
    internal static class SecUtility
    {
        #region Get Value

        internal static bool GetBooleanValue(NameValueCollection config, string valueName, bool defaultValue)
        {
            bool booleanValue;
            var valueValue = config[valueName];
            if (valueValue == null)
            {
                return defaultValue;
            }
            if (!bool.TryParse(valueValue, out booleanValue))
            {
                throw new ProviderException(string.Format(Resources.ValueMustBeBoolean, valueName));
            }
            return booleanValue;
        }

        internal static int GetIntValue(NameValueCollection config, string valueName, int defaultValue, bool zeroAllowed, int maxValueAllowed)
        {
            int intValue;
            var valueValue = config[valueName];
            if (valueValue == null)
            {
                return defaultValue;
            }
            if (!int.TryParse(valueValue, out intValue))
            {
                if (zeroAllowed)
                {
                    throw new ProviderException(string.Format(Resources.ValueMustBeNonNegativeInteger, valueName));
                }
                throw new ProviderException(string.Format(Resources.ValueMustBePositiveInteger, valueName));
            }
            if (zeroAllowed && (intValue < 0))
            {
                throw new ProviderException(string.Format(Resources.ValueMustBeNonNegativeInteger, valueName));
            }
            if (!zeroAllowed && (intValue <= 0))
            {
                throw new ProviderException(string.Format(Resources.ValueMustBePositiveInteger, valueName));
            }
            if ((maxValueAllowed > 0) && (intValue > maxValueAllowed))
            {
                throw new ProviderException(string.Format(Resources.ValueTooBig, valueName, maxValueAllowed.ToString(CultureInfo.InvariantCulture)));
            }
            return intValue;
        }

        #endregion

        #region Check

        internal static void CheckParameter(ref string param, bool checkForNull, bool checkIfEmpty, bool checkForCommas, int maxSize, string paramName)
        {
            if (param == null)
            {
                if (checkForNull)
                {
                    throw new ArgumentNullException(paramName);
                }
            }
            else
            {
                param = param.Trim();
                if (checkIfEmpty && (param.Length < 1))
                {
                    throw new ArgumentException(string.Format(Resources.ParameterCannotBeEmpty, paramName), paramName);
                }
                if ((maxSize > 0) && (param.Length > maxSize))
                {
                    throw new ArgumentException(string.Format(Resources.ParameterTooLong, paramName, maxSize.ToString(CultureInfo.InvariantCulture)), paramName);
                }
                if (checkForCommas && param.Contains(","))
                {
                    throw new ArgumentException(string.Format(Resources.ParameterCannotContainComma, paramName), paramName);
                }
            }
        }

        internal static void CheckPasswordParameter(ref string param, int maxSize, string paramName)
        {
            if (param == null)
            {
                throw new ArgumentNullException(paramName);
            }
            if (param.Length < 1)
            {
                throw new ArgumentException(string.Format(Resources.ParameterCannotBeEmpty, paramName), paramName);
            }
            if ((maxSize > 0) && (param.Length > maxSize))
            {
                throw new ArgumentException(string.Format(Resources.ParameterTooLong, paramName, maxSize.ToString(CultureInfo.InvariantCulture)), paramName);
            }
        }

        internal static void CheckArrayParameter(ref string[] param, bool checkForNull, bool checkIfEmpty, bool checkForCommas, int maxSize, string paramName)
        {
            if (param == null)
            {
                throw new ArgumentNullException(paramName);
            }
            if (param.Length < 1)
            {
                throw new ArgumentException(string.Format(Resources.ParameterArrayEmpty, paramName), paramName);
            }
            var hashtable = new Hashtable(param.Length);
            for (var index = param.Length - 1; index >= 0; index--)
            {
                CheckParameter(ref param[index], checkForNull, checkIfEmpty, checkForCommas, maxSize, string.Format("{0}[ {1} ]", paramName, index.ToString(CultureInfo.InvariantCulture)));
                if (hashtable.Contains(param[index]))
                {
                    throw new ArgumentException(string.Format(Resources.ParameterDuplicateArrayElement, paramName), paramName);
                }
                hashtable.Add(param[index], param[index]);
            }
        }

        #endregion

        #region Validate

        internal static bool ValidateParameter(ref string param, bool checkForNull, bool checkIfEmpty, bool checkForCommas, int maxSize)
        {
            if (param == null)
            {
                return !checkForNull;
            }
            param = param.Trim();
            return (((!checkIfEmpty || (param.Length >= 1)) && ((maxSize <= 0) || (param.Length <= maxSize))) && (!checkForCommas || !param.Contains(",")));
        }

        internal static bool ValidatePasswordParameter(ref string param, int maxSize)
        {
            if (param == null)
            {
                return false;
            }
            if (param.Length < 1)
            {
                return false;
            }
            if ((maxSize > 0) && (param.Length > maxSize))
            {
                return false;
            }
            return true;
        }

        #endregion
    }
}